package com.spzx.report.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.spzx.common.core.utils.uuid.UUID;
import com.spzx.report.aiUtils.PineconeSimilaryUtil;
import com.spzx.report.aiUtils.SpzxAiConst;
import com.spzx.report.aiUtils.SpzxAiQuest;
import com.spzx.report.entity.VOrderInfo;
import com.spzx.report.entity.VOrderInfoJSONObject;
import com.spzx.report.mapper.VOrderInfoMapper;
import com.spzx.report.service.SpzxAiReportService;
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Service
public class SpzxAiReportServiceImpl extends ServiceImpl<VOrderInfoMapper,VOrderInfo> implements SpzxAiReportService {
    @Autowired
    VOrderInfoMapper vOrderInfoMapper;

    @Autowired
    ThreadPoolExecutor threadPoolExecutor;

    @Autowired
    RedisTemplate redisTemplate;

    @Override
    public Map<String, String> getAiReport(String question) {
        SpzxAiQuest spzxAiQuest = new SpzxAiQuest();
        String answerForJson = spzxAiQuest.processQuestion(question);
        VOrderInfoJSONObject vOrderInfoJSONObject = JSON.parseObject(answerForJson,VOrderInfoJSONObject.class);

        //模型匹配数据存入缓存
        String reportDataKey = "report" + UUID.randomUUID().toString().replace("-","");
        redisTemplate.opsForValue().set(reportDataKey,vOrderInfoJSONObject,5, TimeUnit.MINUTES);

        //数据集合打包返回前端
        Map<String,String> reportMap = new HashMap<>();
        reportMap.put("countKey",vOrderInfoJSONObject.getCountKeyword());
        reportMap.put("groupKey",vOrderInfoJSONObject.getGroupKeyword());
        reportMap.put("dataKey",reportDataKey);

        return reportMap;
    }

    @Override
    public List<Map<String, Object>> getDataAiReportFromDB(String dataKey) {
        //缓存中获取模型匹配数据
        VOrderInfoJSONObject vOrderInfoJSONObject = (VOrderInfoJSONObject) redisTemplate.opsForValue().get(dataKey);
        //数据清洗格式化
        VOrderInfoJSONObject vectorData = getVectorData(vOrderInfoJSONObject);

        //生成动态SQL
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper = getMyReportWrapper(queryWrapper,vectorData);
        List<Map<String, Object>> maps = getBaseMapper().selectMaps(queryWrapper);

        return maps;
    }

    //数据库接口测试
    @Override
    public List<VOrderInfo> list() {
        List<VOrderInfo> vOrderInfoList = vOrderInfoMapper.selectList(null);
        return vOrderInfoList;
    }

    //Ai接口测试
    @Override
    public String testAi() {
        //初始化模型
        ChatModel aiChatModel = OpenAiChatModel.builder()
                .apiKey(SpzxAiConst.DASHSCOPE_API_KEY)
                .baseUrl(SpzxAiConst.DASHSCOPE_API_BASEURL)
                .modelName(SpzxAiConst.DEEPSEEK_V3)
                .build();
        return "";
    }


    /***
     * 1 向量数据库匹配相似ai过滤关键词
     * @param vOrderInfoJSONObject
     * @return
     */
    private VOrderInfoJSONObject getVectorData(VOrderInfoJSONObject vOrderInfoJSONObject) {
        //优化代码提高性能 线程池+CompletableFuture


        CompletableFuture<Void> countT = CompletableFuture.runAsync(() -> {
            // 1 分组和聚合关键字处理
            // 此处通过向量数据库，关联用户的信息和本系统的数据字段
            String countKeyword = vOrderInfoJSONObject.getCountKeyword();
            String countKeywordSimilarityEmbeddings = PineconeSimilaryUtil.getPineconeSimilarityEmbeddings(countKeyword, SpzxAiConst.PCK_INDEX_COUNT_KEY_1).get("column");
            // 如果用户没有提及与统计聚合相关信息，则默认以订单个数为统计聚合标准
            if (StringUtils.isEmpty(countKeywordSimilarityEmbeddings)) {
                countKeywordSimilarityEmbeddings = "order_id";
            }
            vOrderInfoJSONObject.setCountKeyword(countKeywordSimilarityEmbeddings.trim());// 聚合关键字
        }, threadPoolExecutor);

        CompletableFuture<Void> groupT = CompletableFuture.runAsync(() -> {
            String groupKeyword = vOrderInfoJSONObject.getGroupKeyword();
            String groupKeywordSimilarityEmbeddings = PineconeSimilaryUtil.getPineconeSimilarityEmbeddings(groupKeyword, SpzxAiConst.PGK_INDEX_GROUP_KEY_1).get("column");
            // 处理向量相似匹配结果
            // 将向量比对后的结果更新到json对象中
            // 如果用户没有提及与分组相关信息，则默认以最近一周的时间作为分组
            if (StringUtils.isEmpty(groupKeywordSimilarityEmbeddings)) {
                groupKeywordSimilarityEmbeddings = "create_date";
            }
            vOrderInfoJSONObject.setGroupKeyword(groupKeywordSimilarityEmbeddings.trim());// 分组关键字
        }, threadPoolExecutor);


        // 2 条件过滤关键字处理，用户的分类关键字，因为系统分类有三级，所以这里需要确定使用哪一个分类，这里默认任何级别都可以，看具体需求
        //String categoryKeyword = vOrderInfoJSONObject.getCategoryKeyword();
        //String category3Name = vOrderInfoJSONObject.getCategory3Name();




        // 分类可能匹配多个,这部分代实际工作中，可以以后单独处理，现在为了实现功能，暂且不用加入(伪代码)
//        if(StringUtils.hasText(categoryKeyword)){
//            List<Map<String, String>> categoryListMap = PineconeSimilaryUtil.getCategoryPineconeSimilarityEmbeddings(categoryKeyword, PineconeConst.PSK_INDEX_SELECT_KEY_1);
//            vOrderInfoJSONObject.setCategory3ListMap(categoryListMap);// 分类条件关键字
//        }
        CompletableFuture<Void> provinceT = CompletableFuture.runAsync(() -> {
            String provinceName = vOrderInfoJSONObject.getProvinceName();
            if (StringUtils.hasText(provinceName)) {
                String provinceNameEmbeddings = PineconeSimilaryUtil.getPineconeSimilarityEmbeddings(provinceName, SpzxAiConst.PSK_INDEX_SELECT_KEY_1).get("word");
                vOrderInfoJSONObject.setProvinceName(provinceNameEmbeddings.trim());// 地区条件关键字
            }
        }, threadPoolExecutor);



        CompletableFuture<Void> tmT = CompletableFuture.runAsync(() -> {
            String tmName = vOrderInfoJSONObject.getTmName();
            if(StringUtils.hasText(tmName)){
                String tmNameEmbeddings =PineconeSimilaryUtil.getPineconeSimilarityEmbeddings(tmName,SpzxAiConst.PSK_INDEX_SELECT_KEY_1).get("word");
                vOrderInfoJSONObject.setTmName(tmNameEmbeddings.trim());// 商标条件关键字
            }
        }, threadPoolExecutor);



        CompletableFuture<Void> skuT = CompletableFuture.runAsync(() -> {
            String skuName = vOrderInfoJSONObject.getSkuName();
            if(StringUtils.hasText(skuName)){
                String skuNameEmbeddings = PineconeSimilaryUtil.getPineconeSimilarityEmbeddings(skuName,SpzxAiConst.PSK_INDEX_SELECT_KEY_1).get("word");
                vOrderInfoJSONObject.setSkuName(skuNameEmbeddings.trim());// 商品条件关键字
            }
        }, threadPoolExecutor);

        CompletableFuture.allOf(
                countT,
                groupT,
                provinceT,
                tmT,
                skuT
        ).join();

        return vOrderInfoJSONObject;
    }


    /***
     * 2 拼接sql语句
     * @param vOrderInfoQueryWrapper
     * @param vectorData
     * @return
     */
    private QueryWrapper<VOrderInfo> getMyReportWrapper(QueryWrapper<VOrderInfo> vOrderInfoQueryWrapper , VOrderInfoJSONObject vectorData) {

        // 聚合统计字段处理
        // 人数user_id or 个数order_id or 总金额order_amount
        String selectStr = null;
        if (vectorData.getCountKeyword().equals("order_amount")) {
            selectStr = "sum(" + vectorData.getCountKeyword() + ") as count";
        } else {
            selectStr = "count(DISTINCT " + vectorData.getCountKeyword() + ") as count";
        }

        // 分组字段处理
        if(vectorData.getGroupKeyword().equals("create_date")){
            vOrderInfoQueryWrapper
                    .select("DATE_FORMAT("+vectorData.getGroupKeyword()+",'%Y-%m-%d') as groupTag", selectStr)
                    .groupBy("DATE_FORMAT("+vectorData.getGroupKeyword()+",'%Y-%m-%d')");
        }else{
            vOrderInfoQueryWrapper
                    .select(vectorData.getGroupKeyword() + " as groupTag", selectStr)
                    .groupBy(vectorData.getGroupKeyword());
        }

        // 条件字段处理
        String skuName = vectorData.getSkuName();
        String provinceName = vectorData.getProvinceName();
        String tmName = vectorData.getTmName();
        //List<Map<String, String>> category3ListMap = vectorData.getCategory3ListMap();

        vOrderInfoQueryWrapper.eq(StringUtils.hasText(skuName),"sku_name",skuName);
        vOrderInfoQueryWrapper.eq(StringUtils.hasText(provinceName),"province_name",provinceName);
        vOrderInfoQueryWrapper.eq(StringUtils.hasText(tmName),"tm_name",tmName);

        return vOrderInfoQueryWrapper;
    }
}
